import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:get_storage/get_storage.dart';

import 'ecgdata.dart';

class WaveParameter {
  Color color = Colors.green;
  // double winWidth = 280; // 波形窗口宽度
  double winWidth = 375; // 波形窗口宽度
  double winHeight = 88; // 波形窗口高度
  int pixelStartPos = 0; // 当前波形起点位置下标
  int pixelWidth = 750; // 窗口可显示的采样点数量
  double heightZoom = 1.0; // 幅度缩放倍数
  double zeroOffset = 0; // 采样值中间值
  double pixelSize = 1 / 3; // 每个采样点在波形上所占宽度
  double yOffset = 44;
  String waveType = 'ecg';
  late GetStorage pref;
  String xZoom = '25mm/s';
  String yZoom = '1.00X';
  bool ruler = true;

  final double ecg1xzoom = 25;

  WaveParameter({required this.pref, required this.waveType}) {
    switch (waveType) {
      case 'ecg':
        color = Colors.green;
        winWidth = 500 + 250 + 85;
        heightZoom = 3;
        pixelWidth = winWidth.toInt() * 4;
        yOffset = 44;
        pixelSize = 1 / 2;
        break;
      case 'pleth':
        color = Colors.yellow;
        zeroOffset = 0;
        heightZoom = 3;
        yOffset = 70;
        winWidth = 500 + 250 + 85;
        pixelWidth = 1000;
        pixelSize = 1 / 2;
        ruler = false;
        break;
      case 'resp':
        color = Colors.blue;
        zeroOffset = 44;
        heightZoom = 2 * 100;
        yOffset = 44;
        winWidth = 500 + 250 + 85;
        pixelWidth = 1000;
        pixelSize = 1 / 2;
        ruler = false;
        break;
    }
    // read();
    calculate();
  }

  void calculate() {
    // print('wave:$waveType');
    // print('wave:$winWidth,$pixelWidth');
    pixelSize = winWidth / pixelWidth.toDouble();
  }

  void read() async {
    bool? key = pref.read(waveType + '_setting_valid');
    if (key != null && key == true) {
      String? y = pref.read(waveType + '_y_zoom');
      if (y != null) {
        yZoom = y.toString();
        switch (yZoom) {
          case '0.125X':
            switch (waveType) {
              case 'ecg':
                heightZoom = ecg1xzoom / 8;
                break;
            }
            break;
          case '0.25X':
            switch (waveType) {
              case 'ecg':
                heightZoom = ecg1xzoom / 4;
                break;
            }
            break;
          case '0.50X':
            switch (waveType) {
              case 'ecg':
                heightZoom = ecg1xzoom / 2;
                break;
            }
            break;
          case '1.00X':
            switch (waveType) {
              case 'ecg':
                heightZoom = ecg1xzoom;
                break;
            }
            break;
          case '2.00X':
            switch (waveType) {
              case 'ecg':
                heightZoom = ecg1xzoom * 2;
                break;
            }
            break;
          case '4.00X':
            switch (waveType) {
              case 'ecg':
                heightZoom = ecg1xzoom * 4;
                break;
            }
            break;
        }
      }
      String? x = pref.read(waveType + '_x_zoom');
      if (x != null) {
        xZoom = x.toString();
        switch (xZoom) {
          case '6.25mm/s':
            switch (waveType) {
              case 'ecg':
                pixelWidth = 6000;
                break;
              case 'pleth':
                pixelWidth = 4000;
                break;
              case 'resp':
                pixelWidth = 14000;
                break;
            }
            break;
          case '12.50mm/s':
            switch (waveType) {
              case 'ecg':
                pixelWidth = 3000;
                break;
              case 'pleth':
                pixelWidth = 2000;
                break;
              case 'resp':
                pixelWidth = 2000;
                break;
            }
            break;
          case '25mm/s':
            switch (waveType) {
              case 'ecg':
                pixelWidth = 1500;
                break;
              case 'pleth':
                pixelWidth = 1000;
                break;
              case 'resp':
                pixelWidth = 1000;
                break;
            }
            break;
          case '50mm/s':
            switch (waveType) {
              case 'ecg':
                pixelWidth = 750;
                break;
              case 'pleth':
                pixelWidth = 500;
                break;
              case 'resp':
                pixelWidth = 500;
                break;
            }
            break;
        }
      }
    }
  }

  Future<void> save() async {
    await pref.write(waveType + '_x_zoom', xZoom);
    await pref.write(waveType + '_y_zoom', yZoom);
    await pref.write(waveType + '_setting_valid', true);
  }
}

class EcgController extends GetxController {
  late GetStorage pref;

  late String sn;
  late String rd;

  var co2 = 0.obs;
  var nibp_hasresult = false.obs;
  var nibp_sys = 0.obs;
  var nibp_map = 0.obs;
  var nibp_dia = 0.obs;
  var hr = 0.obs;
  var temp_hasresult = false.obs;
  var temp = 0.0.obs;
  var resp = 0.obs;

  var temp2_hasresult = false.obs;
  var temp2 = 0.0.obs;

  late Rx<WaveParameter> ecgWaveIContext;
  late Rx<WaveParameter> ecgWaveIIContext;
  late Rx<WaveParameter> ecgWaveV1Context;
  late Rx<WaveParameter> ecgWaveV2Context;
  late Rx<WaveParameter> ecgWaveV3Context;
  late Rx<WaveParameter> ecgWaveV4Context;
  late Rx<WaveParameter> ecgWaveV5Context;
  late Rx<WaveParameter> ecgWaveV6Context;
  late Rx<WaveParameter> ecgWaveIIIContext;
  late Rx<WaveParameter> ecgWaveAVRContext;
  late Rx<WaveParameter> ecgWaveAVLContext;
  late Rx<WaveParameter> ecgWaveAVFContext;
  var waveI = <int>[].obs;
  var waveII = <int>[].obs;
  var waveV1 = <int>[].obs;
  var waveV2 = <int>[].obs;
  var waveV3 = <int>[].obs;
  var waveV4 = <int>[].obs;
  var waveV5 = <int>[].obs;
  var waveV6 = <int>[].obs;
  var waveIII = <int>[].obs;
  var waveAVR = <int>[].obs;
  var waveAVL = <int>[].obs;
  var waveAVF = <int>[].obs;

  late Rx<WaveParameter> respWaveContext;
  late Rx<WaveParameter> plethWaveContext;
  var waveResp = <int>[].obs;
  var waveSpo2 = <int>[].obs;

  var spo2Value = 0.obs;
  var wavePaused = false.obs;

  void addWave(RxList<int> wave, WaveParameter waveContext, List<int> point) {
    // print('addWaveI:${point.length}');
    // ignore: invalid_use_of_protected_member
    // 把新的波形数据添加到原数据里
    wave.value.addAll(point);
    // print('addWaveI total:${waveI.length}');
    // 判断数据是否超过窗口可显示的总数量
    if (wave.length > waveContext.pixelWidth) {
      // 计算需要去掉的老的数据数量
      var skip = wave.length - waveContext.pixelWidth;
      // print('skip:$skip');
      // 去掉的老的数据
      // ignore: invalid_use_of_protected_member
      wave.value = wave.value.sublist(skip);
      // print('addWaveI reamin:${waveI.length}');
      // 调整波形起点位置
      waveContext.pixelStartPos += skip;
      // 波形起点位置超过窗口，回到起点
      if (waveContext.pixelStartPos >= waveContext.pixelWidth) {
        waveContext.pixelStartPos -= waveContext.pixelWidth;
      }
      // print('pixelStartPos:${waveContext.pixelStartPos}');
    }
    // 触发getx重画
    wave.refresh();
  }

  EcgController({required this.sn, required this.rd}) {
    print('EcgController:$sn/$rd');
    pref = GetStorage();
    pref.erase();
    ecgWaveIContext = WaveParameter(pref: pref, waveType: 'ecg').obs;
    ecgWaveIIContext = WaveParameter(pref: pref, waveType: 'ecg').obs;
    ecgWaveV1Context = WaveParameter(pref: pref, waveType: 'ecg').obs;
    ecgWaveV2Context = WaveParameter(pref: pref, waveType: 'ecg').obs;
    ecgWaveV3Context = WaveParameter(pref: pref, waveType: 'ecg').obs;
    ecgWaveV4Context = WaveParameter(pref: pref, waveType: 'ecg').obs;
    ecgWaveV5Context = WaveParameter(pref: pref, waveType: 'ecg').obs;
    ecgWaveV6Context = WaveParameter(pref: pref, waveType: 'ecg').obs;
    ecgWaveIIIContext = WaveParameter(pref: pref, waveType: 'ecg').obs;
    ecgWaveAVRContext = WaveParameter(pref: pref, waveType: 'ecg').obs;
    ecgWaveAVLContext = WaveParameter(pref: pref, waveType: 'ecg').obs;
    ecgWaveAVFContext = WaveParameter(pref: pref, waveType: 'ecg').obs;
    plethWaveContext = WaveParameter(pref: pref, waveType: 'pleth').obs;
    respWaveContext = WaveParameter(pref: pref, waveType: 'resp').obs;

    // plethWaveContext.value.zeroOffset = 0;
    // plethWaveContext.value.heightZoom = 2;
    // plethWaveContext.value.yOffset = 70;
    // plethWaveContext.value.pixelSize = 280 / 400;
    // plethWaveContext.value.pixelWidth = 400;

    // respWaveContext.value.zeroOffset = 0;
    // respWaveContext.value.heightZoom = 2;
    // respWaveContext.value.yOffset = 70;
    // respWaveContext.value.pixelSize = 280 / 400;
    // respWaveContext.value.pixelWidth = 400;

    var src = EcgData().connectRepackDecodedECG(sn, rd);
    // var src = EcgData().connectRepackDecodedECG(sn, "20210623150200");
    src.listen((event) {
      // print('on pkt:${event.sq}');
      if (event.pk.ecg.isNotEmpty) {
        hr.value = event.pk.ecg[0].hr;
        addWave(waveI, ecgWaveIContext.value, event.pk.ecg[0].wv.I);
        addWave(waveII, ecgWaveIIContext.value, event.pk.ecg[0].wv.II);
        addWave(waveV1, ecgWaveV1Context.value, event.pk.ecg[0].wv.V1);
        addWave(waveV2, ecgWaveV2Context.value, event.pk.ecg[0].wv.V2);
        addWave(waveV3, ecgWaveV3Context.value, event.pk.ecg[0].wv.V3);
        addWave(waveV4, ecgWaveV4Context.value, event.pk.ecg[0].wv.V4);
        addWave(waveV5, ecgWaveV5Context.value, event.pk.ecg[0].wv.V5);
        addWave(waveV6, ecgWaveV6Context.value, event.pk.ecg[0].wv.V6);
        addWave(waveIII, ecgWaveIIIContext.value, event.pk.ecg[0].wv.III);
        addWave(waveAVR, ecgWaveAVRContext.value, event.pk.ecg[0].wv.AVR);
        addWave(waveAVL, ecgWaveAVLContext.value, event.pk.ecg[0].wv.AVL);
        addWave(waveAVF, ecgWaveAVFContext.value, event.pk.ecg[0].wv.AVF);
      }
      if (event.pk.spo2.isNotEmpty) {
        addWave(waveSpo2, plethWaveContext.value, event.pk.spo2[0].wave);
        spo2Value.value = event.pk.spo2[0].spo2value;
      }
      if (event.pk.resp.isNotEmpty) {
        addWave(waveResp, respWaveContext.value, event.pk.resp[0].wave);
        resp.value = event.pk.resp[0].rate;
      }
      if (event.pk.nibp.isNotEmpty) {
        if (event.pk.nibp[0].haveresult > 0 && event.pk.nibp[0].working == 0) {
          nibp_hasresult.value = true;
        } else {
          nibp_hasresult.value = false;
        }
        if (event.pk.nibp[0].sys > 0) {
          nibp_sys.value = event.pk.nibp[0].sys;
        }
        if (event.pk.nibp[0].map > 0) {
          nibp_map.value = event.pk.nibp[0].map;
        }
        if (event.pk.nibp[0].dia > 0) {
          nibp_dia.value = event.pk.nibp[0].dia;
        }
      }
      if (event.pk.temp.isNotEmpty && event.pk.temp[0].detectorerror == 0) {
        temp.value = event.pk.temp[0].tempvalue.toDouble() / 10.0;
        temp_hasresult.value = true;
      } else {
        temp_hasresult.value = false;
      }
      if (event.pk.temp.length == 2 && event.pk.temp[1].detectorerror == 0) {
        temp2.value = event.pk.temp[1].tempvalue.toDouble() / 10.0;
        temp2_hasresult.value = true;
      } else {
        temp2_hasresult.value = false;
      }
    });
  }
}
